﻿#include "HttpLogicSystem.h"
#include "HttpConnection.h"
#include "const.h"
#include "MysqlMgr.h"
#include "ConfigMgr.h"
#include "RedisMgr.h"
#include "EmailSender.h"
#include "VerifyGrpcClient.h"
#include "StatusGrpcClient.h"

HttpLogicSystem::HttpLogicSystem() {
	//注册用户逻辑 
	RegPost("/user_register", [](std::shared_ptr<HttpConnection> connection) {
		// 解析请求体 
		auto body_str = boost::beast::buffers_to_string(connection->_request.body().data());
		std::cout << "receive body is " << body_str << std::endl;
		connection->_response.set(http::field::content_type, "text/json");
		Json::Value root;
		Json::Reader reader;
		Json::Value src_root;
		bool parse_success = reader.parse(body_str, src_root);
		// json转换失败
		if (!parse_success) {
			std::cout << "Failed to parse JSON data!" << std::endl;
			root["error"] = ErrorCodes::Error_Json;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		auto email = src_root["email"].asString();
		auto name = src_root["username"].asString();
		auto pwd = src_root["password"].asString();
		auto code = src_root["code"].asString();

		//查询Redis验证码是否正确
		bool ret = RedisMgr::GetInstance()->Get(CODEPREFIX + src_root["email"].asString(), code);
		if (!ret) {
			std::cout << " email not match the code" << std::endl;
			root["error"] = ErrorCodes::EmailNotMatchCode;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		//执行注册，并返回数据库判断用户是否存在
		int uid = MysqlMgr::GetInstance()->RegUser(name, email, pwd);
		//如果 0: {邮箱已存在}, -1: 系统错误  
		if (uid == 0) {
			std::cout << " email exist" << std::endl;
			root["error"] = ErrorCodes::EmailExist;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}
		if (uid == -1) {
			std::cout << " register failed" << std::endl;
			root["error"] = ErrorCodes::RegFailed;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		// 构造成功的响应：
		root["error"] = Success;
		root["uid"] = uid;
		root["email"] = email;
		root["username"] = name;
		root["password"] = pwd;
		std::string jsonstr = root.toStyledString();
		beast::ostream(connection->_response.body()) << jsonstr;
		return true;
		});

	//重置密码回调逻辑
	RegPost("/reset_pwd", [](std::shared_ptr<HttpConnection> connection) {
		auto body_str = boost::beast::buffers_to_string(connection->_request.body().data());
		std::cout << "receive body is " << body_str << std::endl;
		connection->_response.set(http::field::content_type, "text/json");
		Json::Value root;
		Json::Reader reader;
		Json::Value src_root;
		bool parse_success = reader.parse(body_str, src_root);
		//json转换失败
		if (!parse_success) {
			std::cout << "Failed to parse JSON data!" << std::endl;
			root["error"] = ErrorCodes::Error_Json;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		auto email = src_root["email"].asString();
		auto pwd = src_root["password"].asString();
		auto code = src_root["code"].asString();
		UserInfo userInfo;

		//查询Redis验证码是否正确
		bool ret = RedisMgr::GetInstance()->Get(CODEPREFIX + src_root["email"].asString(), code);
		if (!ret) {//验证码不匹配
			std::cout << " email not match the code" << std::endl;
			root["error"] = ErrorCodes::EmailNotMatchCode;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}
	
		//验证码正确，查询数据库判断邮箱和密码是否匹配
		bool email_valid = MysqlMgr::GetInstance()->CheckPwd(email, pwd, userInfo);
		if (!email_valid) {
			std::cout << " email not match the password" << std::endl;
			root["error"] = ErrorCodes::EmailNotMatch;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		//更新密码为最新密码
		bool b_up = MysqlMgr::GetInstance()->UpdatePwd(email, pwd);
		if (!b_up) {
			std::cout << " update pwd failed" << std::endl;
			root["error"] = ErrorCodes::PasswdUpFailed;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		std::cout << "succeed to update password" << pwd << std::endl;
		//构造成功响应：
		root["error"] = Success;
		root["email"] = userInfo.email;
		root["username"] = userInfo.name;
		root["password"] = userInfo.pwd;

		std::string jsonstr = root.toStyledString();
		beast::ostream(connection->_response.body()) << jsonstr;
		return true;
		});

	//用户登录逻辑
	RegPost("/user_login", [](std::shared_ptr<HttpConnection> connection) {
		auto body_str = boost::beast::buffers_to_string(connection->_request.body().data());
		std::cout << "receive body is " << body_str << std::endl;
		connection->_response.set(http::field::content_type, "text/json");
		Json::Value root;
		Json::Reader reader;
		Json::Value src_root;
		bool parse_success = reader.parse(body_str, src_root);
		if (!parse_success) {
			std::cout << "Failed to parse JSON data!" << std::endl;
			root["error"] = ErrorCodes::Error_Json;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		auto email = src_root["email"].asString();
		auto pwd = src_root["password"].asString();
		UserInfo userInfo;
		//查询数据库判断邮箱和密码是否匹配
		bool pwd_valid = MysqlMgr::GetInstance()->CheckPwd(email, pwd, userInfo);
		if (!pwd_valid) {
			std::cout << " user pwd not match" << std::endl;
			root["error"] = ErrorCodes::PasswdInvalid;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		//查询StatusServer找到合适的连接
		auto reply = StatusGrpcClient::GetInstance()->GetResServer(userInfo.uid);
		if (reply.error()) {
			std::cout << " grpc get resource server failed, error is " << reply.error() << std::endl;
			root["error"] = ErrorCodes::RPCFailed;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		std::cout << "succeed to load userinfo , uid is " << userInfo.uid << std::endl;

		//构造成功响应：
		root["error"] = Success;
		root["email"] = userInfo.email;
		root["uid"] = userInfo.uid;
		root["token"] = reply.token();
		root["host"] = reply.host();
		root["port"] = reply.port();
		std::string jsonstr = root.toStyledString();
		beast::ostream(connection->_response.body()) << jsonstr;
		return true;
		});

	//注册对于用户注册时的发送验证码的post请求
	RegPost("/user_register_send_code", [this](std::shared_ptr<HttpConnection> connection) {
		// 解析请求体 
		auto body_str = boost::beast::buffers_to_string(connection->_request.body().data());
		std::cout << "receive body is " << body_str << std::endl;
		connection->_response.set(http::field::content_type, "text/json");
		Json::Value root;
		Json::Reader reader;
		Json::Value src_root;
		bool parse_success = reader.parse(body_str, src_root);
		// json转换失败
		if (!parse_success) {
			std::cout << "Failed to parse JSON data!" << std::endl;
			root["error"] = ErrorCodes::Error_Json;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		// 获取邮箱
		std::string email = src_root["email"].asString();

		//mysql查询邮箱是否存在
		int err = MysqlMgr::GetInstance()->CheckEmail_reg(email);
		//如果邮箱不存在，返回错误码
		if (err == ErrorCodes::EmailExist) {
			std::cout << "email " << email << "exist!" << std::endl;
			root["error"] = err;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}
		//邮箱存在
		// 发送验证码
		auto rpcRsp = VerifyGrpcClient::GetInstance()->GetVerifyCode(email);
		//auto code = _generator();
		//将验证码存入Redis
		//err = RedisMgr::GetInstance()->SetCode(email, code);
		//if (!err)
		//{
		//	std::cout << "set code to redis failed!" << std::endl;
		//	root["error"] = ErrorCodes::RedisSetCodeFailed;
		//	std::string jsonstr = root.toStyledString();
		//	beast::ostream(connection->_response.body()) << jsonstr;
		//	return true;
		//}
		//try
		//{
		//	// 发送验证码
		//	//初始化邮箱发送器
		//	auto& cfg = ConfigMgr::Inst();
		//	EmailSender sender("UTF-8");
		//	// 设置SMTP服务器参数 
		//	sender.SetSmtpServer(cfg["SelfServer"]["UserEmail"], cfg["SelfServer"]["Password"], cfg["SelfServer"]["SMTPHost"], cfg["SelfServer"]["SMTPPort"]);
		//	// 设置发件人信息 
		//	sender.SetSendName("GreatScanner - 验证码"); // 显示名称 
		//	sender.SetSendMail(cfg["SelfServer"]["UserEmail"]);      // 发件邮箱 
		//	// 添加收件人 
		//	sender.AddRecvMail(email); 
		//	// 设置邮件主题（自动Base64编码）
		//	sender.SetSubject("【重要】账户安全验证通知");
		//	// 设置邮件正文内容（自动Base64编码）
		//	std::string htmlContent = HtmlTemplateBuilder::BuildCodeContent(code);
		//	sender.SetBodyContent(htmlContent);
		//	// 添加附件（可选）
		//	// sender.AddAttachment("security_guide.pdf"); 
		//	// 发送邮件 
		//	if (sender.SendMail()) {
		//		std::cout << "[成功] 验证码邮件已发送至您的注册邮箱" << std::endl;
		//	}
		//	else {
		//		std::cerr << "[错误] 邮件发送失败，请检查网络或配置" << std::endl;
		//		root["error"] = ErrorCodes::EmailSendFailed;
		//		std::string jsonstr = root.toStyledString();
		//		beast::ostream(connection->_response.body()) << jsonstr;
		//		return true;
		//	}
		//}
		//catch (...)
		//{
		//	std::cout << "send email failed!" << std::endl;
		//	root["error"] = ErrorCodes::EmailSendFailed;
		//	std::string jsonstr = root.toStyledString();
		//	beast::ostream(connection->_response.body()) << jsonstr;
		//	return true;
		//}
		//构造成功响应：
		root["error"] = rpcRsp.error()/*Success*/;
		std::string jsonstr = root.toStyledString();
		beast::ostream(connection->_response.body()) << jsonstr;
		return true;
		});

	//注册对于密码重置的发送验证码的post请求
	RegPost("/reset_send_code", [this](std::shared_ptr<HttpConnection> connection) {
		// 解析请求体 
		auto body_str = boost::beast::buffers_to_string(connection->_request.body().data());
		std::cout << "receive body is " << body_str << std::endl;
		connection->_response.set(http::field::content_type, "text/json");
		Json::Value root;
		Json::Reader reader;
		Json::Value src_root;
		bool parse_success = reader.parse(body_str, src_root);
		// json转换失败
		if (!parse_success) {
			std::cout << "Failed to parse JSON data!" << std::endl;
			root["error"] = ErrorCodes::Error_Json;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}

		// 获取邮箱
		std::string email = src_root["email"].asString();

		//mysql查询邮箱是否存在
		int err = MysqlMgr::GetInstance()->CheckEmail_reset(email);
		//不存在，返回错误码
		if (err == ErrorCodes::EmailNotExist) {
			std::cout << "email " << email << "not exist!" << std::endl;
			root["error"] = err;
			std::string jsonstr = root.toStyledString();
			beast::ostream(connection->_response.body()) << jsonstr;
			return true;
		}
		//邮箱存在
		// 生成验证码
		//auto code = _generator();
		////将验证码存入Redis
		//err = RedisMgr::GetInstance()->SetCode(email, code);
		//if (!err)
		//{
		//	std::cout << "set code to redis failed!" << std::endl;
		//	root["error"] = ErrorCodes::RedisSetCodeFailed;
		//	std::string jsonstr = root.toStyledString();
		//	beast::ostream(connection->_response.body()) << jsonstr;
		//	return true;
		//}
		//try
		//{
		//	// 发送验证码
		//	//初始化邮箱发送器
		//	auto& cfg = ConfigMgr::Inst();
		//	EmailSender sender("UTF-8");
		//	// 设置SMTP服务器参数 
		//	sender.SetSmtpServer(cfg["SelfServer"]["UserEmail"], cfg["SelfServer"]["Password"], cfg["SelfServer"]["SMTPHost"], cfg["SelfServer"]["SMTPPort"]);
		//	// 设置发件人信息 
		//	sender.SetSendName("GreatScanner - 验证码"); // 显示名称 
		//	sender.SetSendMail(cfg["SelfServer"]["UserEmail"]);      // 发件邮箱 
		//	// 添加收件人 
		//	sender.AddRecvMail(email);
		//	// 设置邮件主题
		//	sender.SetSubject("【重要】账户安全验证通知");
		//	// 设置邮件正文内容
		//	std::string htmlContent = HtmlTemplateBuilder::BuildCodeContent(code);
		//	sender.SetBodyContent(htmlContent);
		//	// 添加附件（可选）
		//	// sender.AddAttachment("security_guide.pdf"); 
		//	// 发送邮件 
		//	if (sender.SendMail()) {
		//		std::cout << "[成功] 验证码邮件已发送至您的注册邮箱" << std::endl;
		//	}
		//	else {
		//		std::cerr << "[错误] 邮件发送失败，请检查网络或配置" << std::endl;
		//		root["error"] = ErrorCodes::EmailSendFailed;
		//		std::string jsonstr = root.toStyledString();
		//		beast::ostream(connection->_response.body()) << jsonstr;
		//		return true;
		//	}
		//}
		//catch (...)
		//{
		//	std::cout << "send email failed!" << std::endl;
		//	root["error"] = ErrorCodes::EmailSendFailed;
		//	std::string jsonstr = root.toStyledString();
		//	beast::ostream(connection->_response.body()) << jsonstr;
		//	return true;
		//}
		auto rpcRsp = VerifyGrpcClient::GetInstance()->GetVerifyCode(email);
		//构造成功响应：
		root["error"] = rpcRsp.error()/*Success*/;
		std::string jsonstr = root.toStyledString();
		beast::ostream(connection->_response.body()) << jsonstr;
		return true;
		});
}

void HttpLogicSystem::RegGet(std::string url, HttpHandler handler) {
	_get_handlers.insert(make_pair(url, handler));
}

void HttpLogicSystem::RegPost(std::string url, HttpHandler handler) {
	_post_handlers.insert(make_pair(url, handler));
}

HttpLogicSystem::~HttpLogicSystem() {

}

bool HttpLogicSystem::HandleGet(std::string path, std::shared_ptr<HttpConnection> con) {
	if (_get_handlers.find(path) == _get_handlers.end()) {
		return false;
	}

	//执行回调
	_get_handlers[path](con);
	return true;
}

bool HttpLogicSystem::HandlePost(std::string path, std::shared_ptr<HttpConnection> con) {
	if (_post_handlers.find(path) == _post_handlers.end()) {
		return false;
	}
	//执行回调
	_post_handlers[path](con);
	return true;
}